package com.ruoyi.system.service.impl;

import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.List;
import java.util.Properties;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.Session;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.mapper.SyncServerMapper;
import com.ruoyi.system.domain.SyncServer;
import com.ruoyi.system.service.ISyncServerService;

/**
 * 服务器Service业务层处理
 * 
 * @author ruoyi
 */
@Service
public class SyncServerServiceImpl implements ISyncServerService 
{
    @Autowired
    private SyncServerMapper syncServerMapper;

    /**
     * 查询服务器
     * 
     * @param serverId 服务器ID
     * @return 服务器
     */
    @Override
    public SyncServer selectSyncServerById(Long serverId)
    {
        return syncServerMapper.selectSyncServerById(serverId);
    }

    /**
     * 查询服务器列表
     * 
     * @param syncServer 服务器
     * @return 服务器
     */
    @Override
    public List<SyncServer> selectSyncServerList(SyncServer syncServer)
    {
        return syncServerMapper.selectSyncServerList(syncServer);
    }

    /**
     * 新增服务器
     * 
     * @param syncServer 服务器
     * @return 结果
     */
    @Override
    public int insertSyncServer(SyncServer syncServer)
    {
        syncServer.setCreateTime(DateUtils.getNowDate());
        syncServer.setCreateBy(SecurityUtils.getUsername());
        return syncServerMapper.insertSyncServer(syncServer);
    }

    /**
     * 修改服务器
     * 
     * @param syncServer 服务器
     * @return 结果
     */
    @Override
    public int updateSyncServer(SyncServer syncServer)
    {
        syncServer.setUpdateTime(DateUtils.getNowDate());
        syncServer.setUpdateBy(SecurityUtils.getUsername());
        return syncServerMapper.updateSyncServer(syncServer);
    }

    /**
     * 批量删除服务器
     * 
     * @param serverIds 需要删除的服务器ID
     * @return 结果
     */
    @Override
    public int deleteSyncServerByIds(Long[] serverIds)
    {
        return syncServerMapper.deleteSyncServerByIds(serverIds);
    }

    /**
     * 删除服务器信息
     * 
     * @param serverId 服务器ID
     * @return 结果
     */
    @Override
    public int deleteSyncServerById(Long serverId)
    {
        return syncServerMapper.deleteSyncServerById(serverId);
    }
    
    /**
     * 测试服务器连接
     * 
     * @param serverId 服务器ID
     * @return 结果
     */
    @Override
    public boolean testConnection(Long serverId)
    {
        SyncServer server = syncServerMapper.selectSyncServerById(serverId);
        if (server == null)
        {
            throw new ServiceException("服务器不存在");
        }
        
        // 根据服务器类型进行不同的连接测试
        if ("0".equals(server.getServerType()))
        {
            // 数据库服务器连接测试
            return testDatabaseConnection(server);
        }
        else if ("1".equals(server.getServerType()))
        {
            // 文件服务器连接测试
            return testFileServerConnection(server);
        }
        else
        {
            throw new ServiceException("不支持的服务器类型");
        }
    }
    
    /**
     * 测试数据库连接
     * 
     * @param server 数据库服务器信息
     * @return 连接结果
     */
    private boolean testDatabaseConnection(SyncServer server)
    {
        Connection conn = null;
        try
        {
            // 根据端口号判断数据库类型，实际应用中可能需要更复杂的逻辑
            String jdbcUrl;
            if (server.getServerPort() == 3306)
            {
                // MySQL
                Class.forName("com.mysql.cj.jdbc.Driver");
                jdbcUrl = "jdbc:mysql://" + server.getServerIp() + ":" + server.getServerPort() + "?useSSL=false&serverTimezone=UTC";
            }
            else if (server.getServerPort() == 1521)
            {
                // Oracle
                Class.forName("oracle.jdbc.driver.OracleDriver");
                jdbcUrl = "jdbc:oracle:thin:@" + server.getServerIp() + ":" + server.getServerPort() + ":orcl";
            }
            else if (server.getServerPort() == 5432)
            {
                // PostgreSQL
                Class.forName("org.postgresql.Driver");
                jdbcUrl = "jdbc:postgresql://" + server.getServerIp() + ":" + server.getServerPort() + "/postgres";
            }
            else if (server.getServerPort() == 1433)
            {
                // SQL Server
                Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
                jdbcUrl = "jdbc:sqlserver://" + server.getServerIp() + ":" + server.getServerPort();
            }
            else
            {
                throw new ServiceException("不支持的数据库类型或端口号");
            }
            
            // 尝试连接数据库，验证用户名和密码
            conn = DriverManager.getConnection(jdbcUrl, server.getUsername(), server.getPassword());
            return true;
        }
        catch (Exception e)
        {
            throw new ServiceException("数据库连接失败: " + e.getMessage());
        }
        finally
        {
            if (conn != null)
            {
                try
                {
                    conn.close();
                }
                catch (Exception e)
                {
                    // 忽略关闭连接时的异常
                }
            }
        }
    }
    
    /**
     * 测试文件服务器连接
     * 
     * @param server 文件服务器信息
     * @return 连接结果
     */
    private boolean testFileServerConnection(SyncServer server)
    {
        // 根据端口号判断可能的协议类型
        // 常见端口: FTP(21), SFTP/SSH(22), FTPS(990)
        if (server.getServerPort() == 22)
        {
            // 很可能是SFTP/SSH连接
            return testSftpConnection(server);
        }
        else
        {
            // 默认尝试FTP连接
            return testFtpConnection(server);
        }
    }
    
    /**
     * 测试FTP连接
     * 
     * @param server 服务器信息
     * @return 连接结果
     */
    private boolean testFtpConnection(SyncServer server)
    {
        FTPClient ftpClient = new FTPClient();
        try
        {
            // 连接FTP服务器
            ftpClient.connect(server.getServerIp(), server.getServerPort());
            
            // 登录FTP服务器
            boolean success = ftpClient.login(server.getUsername(), server.getPassword());
            if (!success)
            {
                throw new ServiceException("FTP服务器登录失败，用户名或密码错误");
            }
            
            // 检查FTP响应码
            int replyCode = ftpClient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(replyCode))
            {
                throw new ServiceException("FTP服务器连接被拒绝");
            }
            
            return true;
        }
        catch (Exception e)
        {
            throw new ServiceException("FTP连接失败: " + e.getMessage());
        }
        finally
        {
            if (ftpClient.isConnected())
            {
                try
                {
                    ftpClient.disconnect();
                }
                catch (Exception e)
                {
                    // 忽略关闭连接时的异常
                }
            }
        }
    }
    
    /**
     * 测试SFTP连接
     * 
     * @param server 服务器信息
     * @return 连接结果
     */
    private boolean testSftpConnection(SyncServer server)
    {
        Session session = null;
        Channel channel = null;
        
        try
        {
            JSch jsch = new JSch();
            session = jsch.getSession(server.getUsername(), server.getServerIp(), server.getServerPort());
            session.setPassword(server.getPassword());
            
            Properties config = new Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            
            // 尝试连接
            session.connect(30000);
            
            // 尝试打开SFTP通道
            channel = session.openChannel("sftp");
            channel.connect(30000);
            
            // 如果能执行到这里，说明连接成功
            return true;
        }
        catch (Exception e)
        {
            throw new ServiceException("SFTP连接失败: " + e.getMessage());
        }
        finally
        {
            // 关闭连接
            if (channel != null && channel.isConnected())
            {
                channel.disconnect();
            }
            if (session != null && session.isConnected())
            {
                session.disconnect();
            }
        }
    }
} 